﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using suirui.ZhuMu.Common;
using suirui.ZhuMu.Model;

namespace suirui.ZhuMu.WebCore
{
    public class SignParamFilterAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext context)
        {
            #region Test
            /*            
            var request_param = context.ActionArguments.Values;
            var queryCollection = context.HttpContext.Request.Query;
            //var queryCollection = context.ActionArguments.Values;
            string account = string.Empty;
            string password = string.Empty;
            long timespan = 0;
            string signature = string.Empty;
            try
            {
                account = queryCollection.Where(p => p.Key == "phone").Select(f => f.Value).FirstOrDefault().ToString();
                password = queryCollection.Where(p => p.Key == "password").Select(f => f.Value).FirstOrDefault().ToString();
                timespan = long.Parse(queryCollection.Where(p => p.Key == "timespan").Select(f => f.Value).FirstOrDefault().ToString());
                signature = queryCollection.Where(p => p.Key == "sign").Select(f => f.Value).FirstOrDefault().ToString();
            }
            catch (Exception ex)
            {
                var apiresult = "参数异常" + ex.ToString();
                context.Result = new JsonResult(apiresult);
            }
            //var accountName = context.RouteData.Values["accountName"].ToString()
            var expires_minute = (timespan - DateTime.Now.Ticks) / 60000000000;
            if (expires_minute > 10 || expires_minute < -10)
            {
                var apimodel = "请求超时" + expires_minute;
                //var json = JsonConvert.SerializeObject(apimodel);
                JsonResult ret = new JsonResult(apimodel);
                context.Result = ret;
            }
            var ok = ("account" + account + "password" + password).Contains(signature);//ToDO 加密解密
            if (ok == false)
            {
                var apimodel = "非法请求";
                var json = JsonConvert.SerializeObject(apimodel);
                JsonResult ret = new JsonResult(apimodel);
                context.Result = ret;
            }
            */
            #endregion

            var p = context.ActionArguments.Values.FirstOrDefault();

            //获取是否签名字段
            string isSign = AppConfigration.Configuration["IsSign"];
            //获取MD5签名字段
            string secretKey = AppConfigration.Configuration["SecurityKey"];
            if (isSign.ToLower() == "false")
            {
                return;
            }
            Type t = p.GetType();
            var propertys = t.GetProperties();
            string sign = "", temp = "";
            long timespan = 0;
            string[] signProp = { "id", "email", "phone", "timespan", "accesstoken", "refreshtoken" };
            var orderPropertys = propertys.OrderBy(p => p.Name); //ASCII码从小到大排序（字典序）
            foreach (var item in orderPropertys)
            {
                string name = item.Name;
                object oValue = item.GetValue(p);
                string value = "";
                if (oValue != null)//如果参数不为空则拼接参数
                {
                    value = oValue.ToString();
                    //判断参数是否为sign，sign不参与签名
                    if (name.ToLower() == "timespan")
                    {
                        timespan = Convert.ToInt64(value);
                    }
                    if (name.ToLower() == "sign")
                    {
                        sign = value;
                    }
                    else if(signProp.Contains(name.ToLower()))
                    {
                        temp += name.ToLower() + "=" + value + "&";
                    }
                }
            }

            var expires_seconds = Math.Abs(timespan - DateTimeHelper.DateTimeToTimeStamp(DateTime.Now));
            string time = AppConfigration.Configuration["ExpiresSeconds"];
            int expireTime = string.IsNullOrWhiteSpace(time) ? 60 : int.Parse(time);
            if (expires_seconds > expireTime)
            {
                var result = new APIResult<long>()
                {
                    Code = ErrorCode.ExpiresSecondsFail,
                    Message = "请求超时",
                    Data = expires_seconds
                };
                context.Result = new JsonResult(result);
            }
            temp += "key=" + secretKey;
            string currentSign = MD5Utils.GetMD5(temp);
            if (sign != "" && sign.ToUpper() == currentSign.ToUpper())
            {
                //签名验证成功
            }
            else
            {
                //签名失败
                var result = new APIResult<string>()
                {
                    Remark = temp,
                    Code = ErrorCode.AuthSignFail,
                    Message = "签名认证失败",
                    Data = currentSign
                };
                context.Result = new JsonResult(result);
            }
            base.OnActionExecuting(context);
        }
    }
}
